﻿using Biotech.Log;
using MaterialDesignThemes.Wpf;
using project.B12.application.Ioc;
using project.B12.application.ViewModels.Dialogs;
using project.B12.application.Views.Dialogs;
using project.B12.IRepository;
using project.B12.IService;
using project.B12.Model.Enums;
using project.B12.Model.Models;
using project.B12.Model.Res;
using project.B12.ViewModels;
using software.Common.MVVM;
using Software.Common.Util.AppConfig;
using SqlSugar;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using WPFDevelopers.Helpers;
using Enum = System.Enum;
using MessageBox = System.Windows.MessageBox;

namespace project.B12.application.ViewModels
{
    public class MonitorViewModel : ObservableObject
    {

        #region Service
        public IServiceDevice serviceDevice { get; set; }

        public IServiceCam serviceCam { get; set; }

        public IServiceImageProcessing serviceImageProcessing { get; set; }

        public IConfigurationFileManagement configurationFileManagement { get; set; }

        public IMICPlateMes mICPlateMes { get; set; }

        public IBacteriaRepository bacteriaRepository { get; set; }

        public IHisRepository hisRepository { get; set; }

        private IMonitorMesRepository monitorMesRepository { get; set; }

        public PublicResourceViewModel publicResourceViewModel { get; set; }
        #endregion

        Dispatcher dispatcher = Dispatcher.CurrentDispatcher;

        public MonitorViewModel(
            IServiceDevice _serviceDevice,
            IServiceCam _serviceCam,
            IServiceImageProcessing _serviceImageProcessing,
            IConfigurationFileManagement _configurationFileManagement,
            IMICPlateMes _mICPlateMes,
            IBacteriaRepository _bacteriaRepository,
            IHisRepository _hisRepository,
            IMonitorMesRepository _monitorMesRepository)
        {
            //注入服务
            serviceDevice = _serviceDevice;
            serviceCam = _serviceCam;
            serviceImageProcessing = _serviceImageProcessing;
            configurationFileManagement = _configurationFileManagement;
            mICPlateMes = _mICPlateMes;
            bacteriaRepository = _bacteriaRepository;
            hisRepository = _hisRepository;
            monitorMesRepository = _monitorMesRepository;
            publicResourceViewModel= ViewModelLocator.PublicResourceViewModel;

            PlateItems = new List<PlateItem>();

            if (UtilAppConfig.ExistItem("SampleIdCount"))
                _sampleCount =int.Parse(UtilAppConfig.GetAppConfig("SampleIdCount"));
            int day=0;
            if (UtilAppConfig.ExistItem("Day"))
                day = int.Parse(UtilAppConfig.GetAppConfig("Day"));
            if (day == 0)
            {
                _day = DateTime.Now.Day;
                UtilAppConfig.UpdateAppConfig("Day", _day.ToString());
            }
            else
                _day = day;

            _currentLeftSampleId = null;
            _currentRightSampleId = null;
            //_leftSampleContinuation = true;
            //_rightSampleContinuation = true;
        }

        public async void WaitInitializtion()
        {
            await Task.Run(async () =>
            {
                InitInfo = "初始化中，请耐心等待...";
                while (true)
                {
                    if (serviceDevice.deviceState == DeviceState.空闲 ||
                    serviceDevice.deviceState == DeviceState.未连接)
                    {
                        InitInfo = null;
                        break;
                    }
                    await Task.Delay(1000);
                }
            });
            init();
            ItemsShelfCurrent = ItemsShelf1;
        }

        #region Model
        private List<string> _sampleTypes = new List<string>();
        private int _sampleCount = 0;
        private string pattern = @"^[a-zA-Z0-9_\-+]+$";
        private bool _isLeftIncrease=true;
        private int _day;
        private string _currentLeftSampleId;
        private string _currentRightSampleId;

        /// <summary>
        /// 是否开启样本编号自增
        /// </summary>
        public bool IsLeftIncrease
        {
            get { return _isLeftIncrease; }
            set
            {
                _isLeftIncrease = value;
                this.RaisePropertyChanged();
            }
        }

        private bool _isRightIncrease=true;
        /// <summary>
        /// 是否开启样本编号自增
        /// </summary>
        public bool IsRightIncrease
        {
            get { return _isRightIncrease; }
            set
            {
                _isRightIncrease = value;
                this.RaisePropertyChanged();
            }
        }

        private bool _isEnabled;
        public bool IsEnabled
        {
            get { return _isEnabled; }
            set { _isEnabled = value; this.RaisePropertyChanged(); }
        }

        private string _initInfo;
        public string InitInfo
        {
            get { return _initInfo; }
            set { _initInfo = value; this.RaisePropertyChanged(); }
        }

        private bool isBusy;
        public bool IsBusy
        {
            get { return isBusy; }
            set 
            { 
                isBusy = value;
                this.RaisePropertyChanged();
            }
        }

        private string scanner;
        public string Scanner
        {
            get { return scanner; }
            set { scanner = value; this.RaisePropertyChanged(); }
        }

        private string roomState;
        public string RoomState
        {
            get{ return roomState; }
            set
            {
                roomState = value;
                this.RaisePropertyChanged();
            }
        }

        private bool _leftSampleContinuation;
        public bool LeftSampleContinuation
        {
            get { return _leftSampleContinuation; }
            set
            {
                _leftSampleContinuation = value;
                this.RaisePropertyChanged();
            }
        }

        private bool _isSkipLeftSample;
        public bool IsSkipLeftSample
        {
            get { return _isSkipLeftSample; }
            set
            {
                _isSkipLeftSample = value;
                this.RaisePropertyChanged();
            }
        }

        private string leftSampleId;
        public string LeftSampleId
        {
            get { return leftSampleId; }
            set
            {
                leftSampleId = value;
                this.RaisePropertyChanged();
            }
        }

        private string leftSampleType;
        public string LeftSampleType
        {
            get { return leftSampleType; }
            set 
            { 
                leftSampleType = value;
                this.RaisePropertyChanged(); 
            }
        }

        private string leftSampleInput;
        public string LeftSampleInput
        {
            get { return leftSampleInput; }
            set
            {
                leftSampleInput = value;
                LeftSampleTypes = publicResourceViewModel.BacteriaNames.Where(o => o.Contains(value)).ToList();
                if(string.IsNullOrEmpty(value))
                    LeftSampleType = null;
                this.RaisePropertyChanged();
            }
        }

        private bool leftSampleEnable=true;
        public bool LeftSampleEnable
        {
            get { return leftSampleEnable; }
            set
            {
                leftSampleEnable = value;
                this.RaisePropertyChanged();
            }
        }

        private List<string> leftSampleTypes;
        public List<string> LeftSampleTypes 
        {
            get { return leftSampleTypes; }
            set
            {
                leftSampleTypes = value;
                this.RaisePropertyChanged();
            }
        }

        private string leftCultivateTime = "18";
        public string LeftCultivateTime
        {
            get { return leftCultivateTime; }
            set
            {
                leftCultivateTime = value;
                this.RaisePropertyChanged();
            }
        }

        private bool leftIsEnabled=true;
        public bool LeftIsEnabled
        {
            get { return leftIsEnabled; }
            set
            {
                leftIsEnabled = value;
                this.RaisePropertyChanged();
            }
        }

        private bool leftCancelEnabled;
        public bool LeftCancelEnabled
        {
            get { return leftCancelEnabled; }
            set
            {
                leftCancelEnabled = value;
                this.RaisePropertyChanged();
            }
        }

        private HoleState leftState;
        public HoleState LeftState
        {
            get { return leftState; }
            set
            {
                leftState = value;
                this.RaisePropertyChanged();
            }
        }

        private List<PlateItem> leftItems = new List<PlateItem>();
        public List<PlateItem> LeftItems
        {
            get { return leftItems; }
            set
            {
                leftItems = value;
                this.RaisePropertyChanged();
            }
        }

        public List<PlateItem> PlateItems { get; set; }

        private string leftName;
        public string LeftName
        {
            get { return leftName; }
            set
            {
                leftName = value; this.RaisePropertyChanged();
            }
        }


        private PlateItem leftSelectedItem;
        public PlateItem LeftSelectedItem
        {
            get { return leftSelectedItem; }
            set
            {
                leftSelectedItem = value; this.RaisePropertyChanged();
            }
        }

        private bool _rightSampleContinuation;
        public bool RightSampleContinuation
        {
            get { return _rightSampleContinuation; }
            set
            {
                _rightSampleContinuation = value;
                this.RaisePropertyChanged();
            }
        }

        private bool _isSkipRightSample;
        public bool IsSkipRightSample
        {
            get { return _isSkipRightSample; }
            set
            {
                _isSkipRightSample = value;
                this.RaisePropertyChanged();
            }
        }

        private string rightSampleId;
        public string RightSampleId
        {
            get {return rightSampleId; }
            set
            {
                rightSampleId = value; this.RaisePropertyChanged();
            }
        }

        private string rightSampleType;
        public string RightSampleType
        {
            get { return rightSampleType; }
            set 
            { 
                rightSampleType = value;
                this.RaisePropertyChanged(); 
            }
        }

        private string rightSampleInput;
        public string RightSampleInput
        {
            get { return rightSampleInput; }
            set
            {
                rightSampleInput = value;
                RightSampleTypes = publicResourceViewModel.BacteriaNames.Where(o => o.Contains(rightSampleInput)).ToList();
                if (string.IsNullOrEmpty(value))
                    RightSampleType = null;
                this.RaisePropertyChanged();
            }
        }

        private List<string> rightSampleTypes = new List<string>();
        public List<string> RightSampleTypes
        {
            get { return rightSampleTypes; }
            set
            {
                rightSampleTypes = value;
                this.RaisePropertyChanged();
            }
        }

        private string rightCultivateTime = "18";
        public string RightCultivateTime
        {
            get { return rightCultivateTime; }
            set
            {
                rightCultivateTime = value;
                this.RaisePropertyChanged();
            }
        }

        private bool rightIsEnabled=true;
        public bool RightIsEnabled
        {
            get { return rightIsEnabled; }
            set
            {
                rightIsEnabled = value;
                this.RaisePropertyChanged();
            }
        }

        private bool rightCancelEnabled;
        public bool RightCancelEnabled
        {
            get { return rightCancelEnabled; }
            set
            {
                rightCancelEnabled = value;
                this.RaisePropertyChanged();
            }
        }

        private HoleState rightState;
        public HoleState RightState
        {
            get { return rightState; }
            set
            {
                rightState = value;
                this.RaisePropertyChanged();
            }
        }

        private List<PlateItem> rightItems=new List<PlateItem>();
        public List<PlateItem> RightItems
        {
            get { return rightItems; }
            set
            {
                rightItems = value;
                this.RaisePropertyChanged();
            }
        }

        private PlateItem rightSelectedItem;
        public PlateItem RightSelectedItem
        {
            get { return rightSelectedItem; }
            set
            {
                rightSelectedItem = value;
                this.RaisePropertyChanged();
            }
        }

        private string plateID;
        public string PlateID
        {
            get { return plateID; }
            set
            {
                plateID = value;
                this.RaisePropertyChanged();
            }
        }

        private ObservableCollection<StateInfo> stateInfos = new ObservableCollection<StateInfo>();
        public ObservableCollection<StateInfo> StateInfos
        {
            get { return stateInfos; }
            set
            {
                stateInfos = value;
                this.RaisePropertyChanged();
            }
        }

        public class StateInfo : ObservableObject
        {
            private HoleState state;
            public HoleState State
            {
                get { return state; }
                set
                {
                    state = value;
                    this.RaisePropertyChanged();
                }
            }

            private int stateCount;
            public int StateCount
            {
                get { return stateCount; }
                set
                {
                    stateCount = value;
                    this.RaisePropertyChanged();
                }
            }
        }

        private bool isTurnEnabled;
        public bool IsTurnEnabled
        {
            
            get { return isTurnEnabled; }
            set
            {
                isTurnEnabled = value;
                this.RaisePropertyChanged();
            }
        }

        private DeviceState deviceState;
        public DeviceState DeviceStatus
        {
            get { return deviceState; }
            set
            {
                deviceState = value;
                this.RaisePropertyChanged();
            }
        }

        string today = "";
        private int currentShelfNumb=1;
        private bool currentShelf1 = true;
        private bool currentShelf2;
        private bool currentShelf3;
        private bool currentShelf4;

        public int CurrentShelfNumb
        {
            get { return currentShelfNumb; }
            set
            {
                currentShelfNumb = value;
                if (value == 1)
                {
                    ItemsShelfCurrent = ItemsShelf1;
                }
                else if (value == 2)
                {
                    ItemsShelfCurrent = ItemsShelf2;
                }
                else if (value == 3)
                {
                    ItemsShelfCurrent = ItemsShelf3;
                }
                else if (value == 4)
                {
                    ItemsShelfCurrent = ItemsShelf4;
                }
                this.RaisePropertyChanged();
            }
        }

        public bool CurrentShelf1
        {
            get { return currentShelf1; }
            set
            {
                currentShelf1 = value;
                if (value)
                    CurrentShelfNumb = 1;

                this.RaisePropertyChanged();
            }
        }

        public bool CurrentShelf2
        {
            get { return currentShelf2; }
            set
            {
                currentShelf2 = value;
                if (value)
                    CurrentShelfNumb = 2;
                this.RaisePropertyChanged();
            }
        }

        public bool CurrentShelf3
        {
            get { return currentShelf3; }
            set
            {
                currentShelf3 = value;
                if (value)
                    CurrentShelfNumb = 3;
                this.RaisePropertyChanged();
            }
        }

        public bool CurrentShelf4
        {
            get { return currentShelf4; }
            set
            {
                currentShelf4 = value;
                if (value)
                    CurrentShelfNumb = 4;
                this.RaisePropertyChanged();
            }
        }

        private List<Table_MonitorMes> itemsShelfCurrent;
        public List<Table_MonitorMes> ItemsShelfCurrent
        {
            get => itemsShelfCurrent;
            set
            {
                itemsShelfCurrent = value;
                itemsShelfCurrent.Reverse();
                this.RaisePropertyChanged();
            }
        }
        private int currentShelfIndex ;
        public int CurrentShelfIndex
        {
            get { return currentShelfIndex; }
            set
            {
                currentShelfIndex = value;
                this.RaisePropertyChanged();
            }
        }

        private int index;
        public int Index
        {
            get { return index; }
            set
            {
                index = value;
                this.RaisePropertyChanged();
            }
        }

        private Dictionary<string, string> testLists = new Dictionary<string, string>();
        public Dictionary<string, string> TestLists
        {
            get { return testLists; }
            set { testLists = value; this.RaisePropertyChanged(); }
        }

        private string currentTest;
        /// <summary>
        /// 药敏板类型名称
        /// </summary>
        public string CurrentTest
        {
            get { return currentTest; }
            set { currentTest = value; this.RaisePropertyChanged(); }
        }
        private int currentIndex;
        public int CurrentIndex
        {
            get { return currentIndex; }
            set { currentIndex = value; this.RaisePropertyChanged(); }
        }

        private List<string> bacteriumLists = new List<string>();
        public List<string> BacteriumLists
        {
            get { return bacteriumLists; }
            set { bacteriumLists = value; this.RaisePropertyChanged(); }
        }

        private string mSearchText;
        public string SearchText
        {
            get { return mSearchText; }
            set
            {
                mSearchText = value; 
                this.RaisePropertyChanged();
                BacteriumLists = bacteriumListsFromDB.Where(x => x.Contains(value)).ToList();
            }
        }
        private string currentBacteriumTest;
        public string CurrentBacteriumTest
        {
            get { return currentBacteriumTest; }
            set { currentBacteriumTest = value; this.RaisePropertyChanged(); }
        }

        private List<string> bacteriumListsFromDB = new List<string>();
        private ConcurrentQueue<Table_MonitorMes> _leftCurrentSamples;
        private ConcurrentQueue<Table_MonitorMes> _rightCurrentSamples;
        /// <summary>
        /// 当前默认的项目
        /// </summary>
        private string _currentPlateType;
        /// <summary>
        /// 当前加样的默认项目
        /// </summary>
        private string _currentSampleType;

        public List<Table_MonitorMes> ItemsShelf1 => serviceDevice.Items64.Where(I => I.Shelf == 1).ToList();
        public List<Table_MonitorMes> ItemsShelf2 => serviceDevice.Items64.Where(I => I.Shelf == 2).ToList();
        public List<Table_MonitorMes> ItemsShelf3 => serviceDevice.Items64.Where(I => I.Shelf == 3).ToList();
        public List<Table_MonitorMes> ItemsShelf4 => serviceDevice.Items64.Where(I => I.Shelf == 4).ToList();

        #endregion

        public RelayCommand AddSampleCommand => new RelayCommand(addSample);

        public RelayCommand TurnShelf1 => new RelayCommand(TurnedShelf1);

        public RelayCommand TurnShelf2 => new RelayCommand(TurnedShelf2);

        public RelayCommand TurnShelf3 => new RelayCommand(TurnedShelf3);

        public RelayCommand TurnShelf4 => new RelayCommand(TurnedShelf4);

        public RelayCommand Clean => new RelayCommand(CleanDonePlate);

        public RelayCommand LeftAddSample => new RelayCommand(AddLeftSample);

        public RelayCommand LeftCancel => new RelayCommand(CancelLeftSamples);

        public RelayCommand LeftSpecialSample => new RelayCommand(AddLeftSpecialSample);

        public RelayCommand RightSpecialSample => new RelayCommand(AddRightSpecialSample);

        public RelayCommand RightAddSample => new RelayCommand(AddRightSample);

        public RelayCommand RightCancel => new RelayCommand(CancelRightSample);


        public RelayCommand<int> TakeAwayCommand => new RelayCommand<int>((index) =>
        {
            var currentPlate = serviceDevice.Items64.Where(o => o.Shelf == CurrentShelfNumb && o.Index == index).First();
            if (currentPlate.State == HoleState.DONE)
            {
                CleanCurrentPlate(currentPlate);
                MessageBox.Show(Resources.PlateDone);
                LoggerFactory.Instance.CurrentLogger.LogInfo("手动取板：" + currentPlate.Shelf + " " + currentPlate.Index + " " + currentPlate.PlateID, "", "软件");
                return;
            }

            AddPlateIdViewModel vm = ViewModelLocator.AddPlateIdViewModel;
            vm.SampleTypes = TestLists.Values.ToList();
            vm.Tip = string.Empty;
            vm.Shelf = CurrentShelfNumb;
            vm.Index = index;
            if (currentPlate.State != HoleState.NULL)
            {
                vm.SampleType = currentPlate.PlateType;
                vm.PlateId = currentPlate.PlateID;
            }
            else
            {
                vm.SampleType = _currentPlateType;
                vm.PlateId = null;
            }
            AddPlateId addPlate=new AddPlateId();
            addPlate.DataContext = vm;
            vm.ReturnPlate -= SetPlateId;
            vm.ReturnPlate += SetPlateId;   
            vm.ReturnPlateContinue-= SetPlateIdContinue;
            vm.ReturnPlateContinue += SetPlateIdContinue;
            vm.ConfirmDelete-= DeletePlateId;
            vm.ConfirmDelete += DeletePlateId;
            App.Current.Dispatcher.Invoke(() =>
            {
                Index = index;
                DialogHost.Show(addPlate, "Main");
            });
        });


        #region 方法
        private void init()
        {
            DateTime dt = DateTime.Now;
            string ds = dt.ToString("yyMMdd");
            today = ds;
            if (mICPlateMes.microplateAntibioticConcentrationMes != null && mICPlateMes.microplateAntibioticConcentrationMes.Count > 0)
            {
                for (int i = 0; i < mICPlateMes.microplateAntibioticConcentrationMes.Count; i++)
                {
                    var name = mICPlateMes.microplateAntibioticConcentrationMes[i].name;
                   
                    TestLists.Add(name, name);
                    int platCount = serviceDevice.Items64.Where(o => o.PlateType == name && o.State == HoleState.NULL).Count();
                    if (platCount == 0)
                    {
                        PlateItems.Add(new PlateItem { Name = name, Count = platCount, IsEnabled = false });
                        continue;
                    }
                    PlateItems.Add(new PlateItem { Name = name, Count = platCount, IsEnabled = true });
                }
                LeftItems = PlateItems.OrderByDescending(o => o.Count).ToList();
                RightItems = PlateItems.OrderByDescending(o => o.Count).ToList();
                CurrentIndex = 0;
            }
            var bacterias = bacteriaRepository.QueryAllBacteria();
            foreach (var bacteria in bacterias)
            {
                _sampleTypes.Add(bacteria.CN_Name);
            }
            publicResourceViewModel.BacteriaNames = new ObservableCollection<string>(_sampleTypes);
            LeftSampleTypes = _sampleTypes;
            RightSampleTypes= _sampleTypes;

            SearchText = "";
            SetStateInfos();
            LeftState = HoleState.Free;
            RightState = HoleState.Free;
            _ =RefreshTimeValue();
            IsEnabled = true;
        }

        private void SetStateInfos()
        {      
            foreach (HoleState state in Enum.GetValues(typeof(HoleState)))
            {
                AddStateInfo(state);
            }
        }

        private void AddStateInfo(HoleState state)
        {
            int count = 0;
            switch (state)
            {
                case HoleState.NULL:
                case HoleState.Free:
                case HoleState.Incubation:
                case HoleState.DONE:
                    count = serviceDevice.Items64.Where(o => o.State == state).Count();
                    StateInfos.Add(new StateInfo { State = state, StateCount = count });
                    break;
                case HoleState.Error:
                    {
                        int sampleErrorCount= serviceDevice.Items64.Where(o => o.State ==HoleState.SampleError).Count();
                        int photoErrorCount = serviceDevice.Items64.Where(o => o.State == HoleState.PhotographError).Count();
                        int errorCount = serviceDevice.Items64.Where(o => o.State == state).Count();
                        StateInfos.Add(new StateInfo { State = state, StateCount = (sampleErrorCount+ photoErrorCount+ errorCount) });
                        break;
                    }
                case HoleState.Sample:
                    {
                        int sampleWaitingCount = serviceDevice.Items64.Where(o => o.State == HoleState.WaitingForSample).Count();
                        int samplingCount = serviceDevice.Items64.Where(o => o.State == HoleState.SAMPLING).Count();
                        StateInfos.Add(new StateInfo { State = state, StateCount = (sampleWaitingCount + samplingCount) });
                        break;
                    }
                case HoleState.Photo:
                    {
                        int photoWaitingCount = serviceDevice.Items64.Where(o => o.State == HoleState.WaitingForPhotograph).Count();
                        int photoCount = serviceDevice.Items64.Where(o => o.State == HoleState.Photograph).Count();
                        StateInfos.Add(new StateInfo { State = state, StateCount = (photoWaitingCount + photoCount) });
                        break;
                    }
            }
        }

        private void TurnedShelf1()
        {
            if (serviceDevice.CurrentShelfIndex == 1)
                return;
  
            serviceDevice.TurnShelf(1);
        }

        private void TurnedShelf2()
        {
            if (serviceDevice.CurrentShelfIndex == 2)
                return;

            serviceDevice.TurnShelf(2);
        }

        private void TurnedShelf3()
        {
            if (serviceDevice.CurrentShelfIndex == 3)
                return;

            serviceDevice.TurnShelf(3);
        }

        private void TurnedShelf4()
        {
            if (serviceDevice.CurrentShelfIndex == 4)
                return;

            serviceDevice.TurnShelf(4);
        }

        /// <summary>
        /// 执行左加样
        /// </summary>
        private void AddLeftSample()
        { 
            try
            {
                if (LeftIsEnabled)
                {
                    int time = -1;
                    if (!CheckCondition(0, ref time))
                        return;
                    LeftIsEnabled = false;
                    LeftCancelEnabled = true;
                    _leftCurrentSamples = new ConcurrentQueue<Table_MonitorMes>();
                    if (LeftSampleContinuation)
                    {
                        SampleLeftContinuation(time);
                    }
                    else
                    {
                        Table_MonitorMes monitorMes = serviceDevice.Items64.Where(o => o.State == HoleState.Free && o.PlateType == LeftSelectedItem.Name).First();
                        SetLeftSample(monitorMes, time);
                    }
                }
            }
            catch
            {
                MessageBox.Show(Resources.AddSampleInformationError);
            }
        }

        /// <summary>
        /// 左加样连续加样
        /// </summary>
        /// <param name="time"></param>
        private void SampleLeftContinuation(int time)
        {
            List<Table_MonitorMes> monitorMeses = serviceDevice.Items64.Where(o => o.State == HoleState.Free && o.PlateType == LeftSelectedItem.Name).ToList();
            for(int i=0;i<2;i++)
            {
                SetLeftSample(monitorMeses[i], time);
            }
        }

        /// <summary>
        /// 左加样药敏板
        /// </summary>
        /// <param name="monitorMes"></param>
        /// <param name="time">孵育时间</param>
        private void SetLeftSample(Table_MonitorMes monitorMes, int time)
        {
            if (IsLeftIncrease)
            {
                IncreaseLeftSampleID(monitorMes);
            }
            else
                monitorMes.SampleID = LeftSampleId;
            monitorMes.SampleType = LeftSampleType;
            monitorMes.CultureTime = time * 60 * 60;
            monitorMes.LorR = 0;

            if(IsSkipLeftSample)
            {
                monitorMes.AddSampleTime = DateTime.Now;
                monitorMes.State = HoleState.Incubation;
                CleanLeftPlate();
                LoggerFactory.Instance.CurrentLogger.LogInfo(monitorMes.PlateID + "跳过左加样", "", "软件");
            }
            else
            {
                monitorMes.State = HoleState.WaitingForSample;
                _leftCurrentSamples.Enqueue(monitorMes);
                LoggerFactory.Instance.CurrentLogger.LogInfo(monitorMes.PlateID + "申请左加样", "", "软件");
            }

            if(serviceDevice.IsPhotoInterval)
            {
                monitorMes.PhotoIntervalTime=publicResourceViewModel.PhotoTime;
            }
            monitorMesRepository.UpdateMonitorMes(monitorMes);
        }

        /// <summary>
        /// 左加样样本编号自增
        /// </summary>
        /// <param name="monitorMes"></param>
        private void IncreaseLeftSampleID(Table_MonitorMes monitorMes)
        {
            if(string.IsNullOrEmpty(LeftSampleId))
            {
                LeftSampleId = LeftSampleId + $"{_sampleCount:D3}";
                _sampleCount++;
                UtilAppConfig.UpdateAppConfig("SampleIdCount", _sampleCount.ToString());
                monitorMes.SampleID = LeftSampleId;
                return;
            }

            int length = LeftSampleId.Length;
            if (Regex.IsMatch(LeftSampleId,"[0-9]+$"))
            {
                int number = int.Parse(LeftSampleId.Substring(length - 1)) + 1;
                _currentLeftSampleId = LeftSampleId.Substring(0, length - 1) + number.ToString();
            }
            else
            {
                LeftSampleId= LeftSampleId + $"{_sampleCount:D3}";
                _sampleCount++;
                UtilAppConfig.UpdateAppConfig("SampleIdCount", _sampleCount.ToString());
            }
            monitorMes.SampleID= LeftSampleId;
        }

        /// <summary>
        /// 检查申请加样信息
        /// </summary>
        /// <param name="i">i=0表示左加样</param>
        /// <param name="time">返回的培育时间</param>
        /// <returns>true表示通过</returns>
        private bool CheckCondition(int i,ref int time)
        {
            int cout = int.Parse(UtilAppConfig.GetAppConfig("SampleIdCount"));
            if(_sampleCount!=cout)
                _sampleCount=cout;

            time = -1;
            string cultivateTime = i == 0 ? LeftCultivateTime : RightCultivateTime;
            if (!int.TryParse(cultivateTime, out time))
            {
                WPF.Controls.Message.Push(Resources.CultivateTimeWarning, MessageBoxImage.Warning);
                return false;
            }
            if (time < 0 || time > 168)
            {
                WPF.Controls.Message.Push(Resources.CultivateTimeWarning, MessageBoxImage.Warning);
                return false;
            }

            PlateItem item = i == 0 ? LeftSelectedItem : RightSelectedItem;
            if (item == null)
            {
                WPF.Controls.Message.Push(Resources.SampleAddError, MessageBoxImage.Warning);
                return false;
            }

            string sampleId = i == 0 ? LeftSampleId : RightSampleId;
            bool isIncrease= i == 0 ? IsLeftIncrease : IsRightIncrease;
            if (string.IsNullOrEmpty(sampleId))
            {
                if(!isIncrease)
                {
                    WPF.Controls.Message.Push(Resources.SampleIdAddWarning, MessageBoxImage.Warning);
                    return false;
                }
            }
            else
            {
                if (!Regex.IsMatch(sampleId, pattern))
                {
                    WPF.Controls.Message.Push(Resources.PlateIDRules, MessageBoxImage.Warning);
                    return false;
                }
            }
            

            string sampleType=i==0? LeftSampleType : RightSampleType;
            if (string.IsNullOrEmpty(sampleType))
            {
                WPF.Controls.Message.Push(Resources.SampleTypeWarning, MessageBoxImage.Warning);
                return false;

            }
            return true;
        }

        /// <summary>
        /// 取消左加样
        /// </summary>
        private void CancelLeftSamples()
        {
            if (_leftCurrentSamples== null|| _leftCurrentSamples.Count==0)
                return;
            MessageBoxResult result = MessageBox.Show(Resources.IsCancelSample, "", MessageBoxButton.OKCancel, MessageBoxImage.Question);
            if (result != MessageBoxResult.OK)
                return;

            foreach (var item in _leftCurrentSamples)
            {
                var monitorMeses = serviceDevice.Items64.Where(o => o.Shelf == item.Shelf && o.Index == item.Index);
                Table_MonitorMes monitorMes = monitorMeses.First();
                monitorMes.SampleID = null;
                monitorMes.SampleType = "";
                monitorMes.CultureTime = 0;
                if (monitorMes.State == HoleState.WaitingForSample)
                {
                    monitorMes.State = HoleState.Free;
                }
                else if (monitorMes.State == HoleState.SAMPLING)
                {
                    serviceDevice.DiscontinueDevice();
                    monitorMes.State = HoleState.SampleError;
                }
                LoggerFactory.Instance.CurrentLogger.LogInfo(monitorMes.PlateID + "取消左加样", "", "软件");
                monitorMesRepository.UpdateMonitorMes(monitorMes);
            }
            _leftCurrentSamples = new ConcurrentQueue<Table_MonitorMes>();
            CleanLeftPlate();
        }

        private void CleanLeftPlate()
        {
            if(LeftSelectedItem == null||LeftSelectedItem.Count==0 )
                LeftSelectedItem = null;
            LeftIsEnabled = true;
            LeftCancelEnabled = false;
            LeftState = HoleState.Free;
            LeftSampleId=_currentLeftSampleId;
        }

        private void AddLeftSpecialSample()
        {
            var monitors = serviceDevice.Items64.Where(o => o.State == HoleState.Free);
            if (monitors == null || monitors.Count() == 0)
            {
                WPF.Controls.Message.Push("当前没有空闲板", MessageBoxImage.Warning);
                return;
            }

            SpecialSampleViewModel vm = new SpecialSampleViewModel(serviceDevice,mICPlateMes);
            vm.LorR = 0;
            SpecialSampleView addPlate = new SpecialSampleView() { DataContext = vm };
            App.Current.Dispatcher.Invoke(() =>
            {
                DialogHost.Show(addPlate, "Main");
            });
        }

        private void AddRightSpecialSample()
        {
            var monitors = serviceDevice.Items64.Where(o => o.State == HoleState.Free);
            if (monitors == null || monitors.Count() == 0)
            {
                WPF.Controls.Message.Push("当前没有空闲板", MessageBoxImage.Warning);
                return;
            }

            SpecialSampleViewModel vm = new SpecialSampleViewModel(serviceDevice, mICPlateMes);
            vm.LorR = 1;
            SpecialSampleView addPlate = new SpecialSampleView() { DataContext = vm };
            App.Current.Dispatcher.Invoke(() =>
            {
                DialogHost.Show(addPlate, "Main");
            });
        }

        private void CleanRightPlate()
        {
            //RightSampleId = null;
            //RightSelectedItem = null;
            if (RightSelectedItem == null||RightSelectedItem.Count == 0)
                RightSelectedItem = null;
            RightIsEnabled = true;
            RightCancelEnabled = false;
            RightState = HoleState.Free;
            RightSampleId = _currentRightSampleId;
        }

        private void AddRightSample()
        {
            try
            {
                if (RightIsEnabled)
                {
                    int time = -1;
                    if (!CheckCondition(1, ref time))
                        return;
                    RightIsEnabled = false;
                    RightCancelEnabled= true;
                    _rightCurrentSamples = new ConcurrentQueue<Table_MonitorMes>();
                    if (RightSampleContinuation)
                    {
                        SampleRightContinuation(time);
                    }
                    else
                    {
                        Table_MonitorMes monitorMes = serviceDevice.Items64.Where(o => o.State == HoleState.Free && o.PlateType == RightSelectedItem.Name).First();
                        SetRightSample(monitorMes, time);
                    }
                }
            }
            catch
            {
                MessageBox.Show(Resources.AddSampleInformationError);
            }
        }

        /// <summary>
        /// 右加样连续加样
        /// </summary>
        /// <param name="time"></param>
        private void SampleRightContinuation(int time)
        {
            List<Table_MonitorMes> monitorMeses = serviceDevice.Items64.Where(o => o.State == HoleState.Free && o.PlateType == RightSelectedItem.Name).ToList();
            for(int i=0;i<2;i++)
            {
                SetRightSample(monitorMeses[i], time);
            }
        }

        private void SetRightSample(Table_MonitorMes monitorMes, int time)
        {
            if (IsRightIncrease)
            {
                IncreaseRightSampleID(monitorMes);
            }
            else
                monitorMes.SampleID = RightSampleId;

            monitorMes.SampleType = RightSampleType;
            monitorMes.CultureTime = time * 60 * 60;
            monitorMes.LorR = 1;

            if(IsSkipRightSample)
            {
                monitorMes.AddSampleTime = DateTime.Now;
                monitorMes.State = HoleState.Incubation;
                CleanRightPlate();
                LoggerFactory.Instance.CurrentLogger.LogInfo(monitorMes.PlateID + "跳过右加样", "", "软件");
            }
            else
            {
                //monitorMes.State = HoleState.WaitingForSample;
                //_rightCurrentSamples.Enqueue(monitorMes);
                //LoggerFactory.Instance.CurrentLogger.LogInfo(monitorMes.PlateID + "申请右加样", "", "软件");
            }
            if (serviceDevice.IsPhotoInterval)
            {
                monitorMes.PhotoIntervalTime = publicResourceViewModel.PhotoTime;
            }
            
            monitorMes.State = HoleState.DONE;
            monitorMes.IsReport = true;
            monitorMesRepository.UpdateMonitorMes(monitorMes);
            serviceDevice.IsUpdateWellPlateIDList = true;
        }

        /// <summary>
        /// 右加样样本编号自增
        /// </summary>
        /// <param name="monitorMes"></param>
        private void IncreaseRightSampleID(Table_MonitorMes monitorMes)
        {
            if(string.IsNullOrEmpty(RightSampleId))
            {
                RightSampleId = RightSampleId + $"{_sampleCount:D3}";
                _sampleCount++;
                UtilAppConfig.UpdateAppConfig("SampleIdCount", _sampleCount.ToString());
                monitorMes.SampleID = RightSampleId;
                return;
            }

            int length = RightSampleId.Length;
            if (Regex.IsMatch(RightSampleId, "[0-9]+$"))
            {
                int number = int.Parse(RightSampleId.Substring(length - 1)) + 1;
                _currentRightSampleId = RightSampleId.Substring(0, length - 1) + number.ToString();
            }
            else
            {
                RightSampleId = RightSampleId + $"{_sampleCount:D3}";
                _sampleCount++;
                UtilAppConfig.UpdateAppConfig("SampleIdCount", _sampleCount.ToString());
            }
            monitorMes.SampleID = RightSampleId;
        }

        private void CancelRightSample()
        {
            if (_rightCurrentSamples == null|| _rightCurrentSamples.Count==0)
            {
                RightIsEnabled = true;
                return;
            }
               
            MessageBoxResult result = MessageBox.Show(Resources.IsCancelSample, "", MessageBoxButton.OKCancel, MessageBoxImage.Question);
            if (result != MessageBoxResult.OK)
                return;

            foreach (var item in _rightCurrentSamples)
            {
                var monitorMeses = serviceDevice.Items64.Where(o => o.Shelf == item.Shelf && o.Index == item.Index);
                Table_MonitorMes monitorMes = monitorMeses.First();
                monitorMes.SampleID = null;
                monitorMes.SampleType = "";
                monitorMes.CultureTime = 0;
                if (monitorMes.State == HoleState.WaitingForSample)
                {
                    monitorMes.State = HoleState.Free;
                }
                else if (monitorMes.State == HoleState.SAMPLING)
                {
                    serviceDevice.DiscontinueDevice();
                    monitorMes.State = HoleState.SampleError;
                }
                LoggerFactory.Instance.CurrentLogger.LogInfo(monitorMes.PlateID + "取消右加样", "", "软件");
                monitorMesRepository.UpdateMonitorMes(monitorMes);
            }
            _rightCurrentSamples = new ConcurrentQueue<Table_MonitorMes>();
            CleanRightPlate();
        }

        private void SetPlateId(List<string> samples,int tempIndex)
        {
            var temp = ItemsShelfCurrent[16- tempIndex];
            ItemsShelfCurrent[16 - tempIndex].PlateID = samples[0];
            ItemsShelfCurrent[16 - tempIndex].PlateType = samples[1];
            _currentPlateType = samples[1];
            if (temp.State== HoleState.NULL)
            {
                ItemsShelfCurrent[16 - tempIndex].State = HoleState.Free;
                ItemsShelfCurrent[16 - tempIndex].LoadTime = DateTime.Now;
                monitorMesRepository.AddMonitorMes(ItemsShelfCurrent[16 - tempIndex]);
                //serviceDevice.AddNoNeedScan(serviceDevice.CurrentShelfIndex, index);
                LoggerFactory.Instance.CurrentLogger.LogInfo("手动放板："+ CurrentShelfNumb +" "+ tempIndex + " "+ samples[0], "", "软件");
            }
            else
            {
                monitorMesRepository.UpdateMonitorMes(ItemsShelfCurrent[16 - tempIndex]);
                LoggerFactory.Instance.CurrentLogger.LogInfo("手动修改：" + CurrentShelfNumb + " " + tempIndex + " " + samples[0], "", "软件");
            }
            if (DialogHost.IsDialogOpen("Main"))
                DialogHost.Close("Main", true);
        }

        /// <summary>
        /// 项目Id，项目，培育仓加，位置
        /// </summary>
        /// <param name="samples"></param>
        private void SetPlateIdContinue(List<string> samples)
        {
            int shelf=int.Parse(samples[2]);
            int index = int.Parse(samples[3]);
            var temp = serviceDevice.Items64.Where(o => o.Shelf == shelf && o.Index == index).First();
            temp.PlateID = samples[0];
            temp.PlateType= samples[1];
            temp.State = HoleState.Free;
            temp.LoadTime = DateTime.Now;
            monitorMesRepository.AddMonitorMes(temp);
            LoggerFactory.Instance.CurrentLogger.LogInfo("手动放板：" + shelf + " " + index + " " + samples[0], "", "软件");
        }

        private void DeletePlateId()
        {
            ItemsShelfCurrent[16 - Index].PlateID = null;
            ItemsShelfCurrent[16 - Index].PlateType = null; 
            ItemsShelfCurrent[16 - Index].State = HoleState.NULL;
            ItemsShelfCurrent[16 - Index].SampleID = null;
            ItemsShelfCurrent[16 - Index].SampleType = null;
            ItemsShelfCurrent[16 - Index].AddSampleTime =null;
            ItemsShelfCurrent[16 - Index].Countdown = null;
            monitorMesRepository.DeleteMonitorMes(ItemsShelfCurrent[16 - Index]);
            LoggerFactory.Instance.CurrentLogger.LogInfo($"删除第{CurrentShelfNumb}架{index}的板", "", "软件");
            if (DialogHost.IsDialogOpen("Main"))
                DialogHost.Close("Main", true);
        }

        private void CleanCurrentPlate(Table_MonitorMes currentPlate)
        {
            var monitorMes = serviceDevice.Items64.Where(o => o.Shelf == currentPlate.Shelf && o.Index == currentPlate.Index).First();

            int index = serviceDevice.Items64.IndexOf(monitorMes);
            serviceDevice.Items64[index].State = HoleState.NULL;
            serviceDevice.Items64[index].PlateID = null;
            serviceDevice.Items64[index].PlateType = null;
            serviceDevice.Items64[index].SampleID = null;
            serviceDevice.Items64[index].SampleType = null;

            monitorMesRepository.DeleteMonitorMes(monitorMes);
        }

        /// <summary>
        /// 每秒更新主界面时间
        /// </summary>
        private async Task RefreshTimeValue()
        {
            await Task.Run(async() =>
            {
                while (true)
                {
                    if (_day!=DateTime.Now.Day)
                    {
                        _day = DateTime.Now.Day;
                        UtilAppConfig.UpdateAppConfig("Day", _day.ToString());
                        _sampleCount = 1;
                        UtilAppConfig.UpdateAppConfig("SampleIdCount", _sampleCount.ToString());
                    }
                    UpdateSample();
                    UpdatePlateState();
                    UpdateSampleState();
                    if (!serviceDevice.isConnect)
                    {
                        continue;
                    }
                    AvoidTurned();
                   
                    await Task.Delay(1000);
                }
            });
        }

        private void UpdateSample()
        {
            if (mICPlateMes.microplateAntibioticConcentrationMes == null && mICPlateMes.microplateAntibioticConcentrationMes.Count <= 0)
                return;

            for (int i = 0; i < mICPlateMes.microplateAntibioticConcentrationMes.Count; i++)
            {
                var name = mICPlateMes.microplateAntibioticConcentrationMes[i].name;
                if (!PlateItems.Any(o => o.Name == name))
                {
                    PlateItems.Add(new PlateItem() { Name = name, Count = 0 });
                    TestLists.Add(name, name);
                    LeftItems = PlateItems.OrderByDescending(o => o.Count).ToList();
                    RightItems = PlateItems.OrderByDescending(o => o.Count).ToList();
                }
                int platCount = serviceDevice.Items64.Where(o => o.PlateType == name && o.State == HoleState.Free).Count();

                if (PlateItems.FirstOrDefault(o => o.Name == name).Count != platCount)
                {
                    UpdateFromPlatCount(name, platCount);
                }
            }
        }

        /// <summary>
        /// 一键清空已完成板
        /// </summary>
        private void CleanDonePlate()
        {
            var items=serviceDevice.Items64.Where(o => o.State == HoleState.DONE).ToList();
            if(items.Count > 0||items!=null)
            {
                MessageBoxResult result = MessageBox.Show(Resources.IsCleanDonePlate, "", MessageBoxButton.OKCancel, MessageBoxImage.Question);
                if (result == MessageBoxResult.OK)
                {
                    foreach (var item in items)
                    {
                        CleanCurrentPlate(item);
                    }
                }
            }
        }

        /// <summary>
        /// 根据微孔板数量更新
        /// </summary>
        private void UpdateFromPlatCount(string name,int platCount)
        {
            var item = PlateItems.FirstOrDefault(o => o.Name == name);
            if (platCount == 0)
            {
                //PlateItems[index].Count = platCount;
                item.IsEnabled = false;
            }
            else
            {
                //PlateItems[index].Count = platCount;
                item.IsEnabled = true;
            }

            item.Count = platCount;
            LeftItems = PlateItems.OrderByDescending(o => o.Count).ToList();
            RightItems = PlateItems.OrderByDescending(o => o.Count).ToList();
        }

        /// <summary>
        /// 更新微孔板信息
        /// </summary>
        private void UpdatePlateState()
        {
            int i = 0;
            foreach(var item in StateInfos)
            {
                
                UpdateStateCount(item.State, i);
                i++;
            }
        }

        private void UpdateStateCount(HoleState state, int index)
        {
            int count = 0;
            switch (state)
            {
                case HoleState.NULL:
                case HoleState.Free:
                case HoleState.Incubation:
                case HoleState.DONE:
                    count = serviceDevice.Items64.Where(o => o.State == state).Count();
                    break;
                case HoleState.Error:
                    {
                        int sampleErrorCount = serviceDevice.Items64.Where(o => o.State == HoleState.SampleError).Count();
                        int photoErrorCount = serviceDevice.Items64.Where(o => o.State == HoleState.PhotographError).Count();
                        int errorCount = serviceDevice.Items64.Where(o => o.State == state).Count();
                        count = sampleErrorCount + photoErrorCount + errorCount;
                        break;
                    }
                case HoleState.Sample:
                    {
                        int sampleWaitingCount = serviceDevice.Items64.Where(o => o.State == HoleState.WaitingForSample).Count();
                        int samplingCount = serviceDevice.Items64.Where(o => o.State == HoleState.SAMPLING).Count();
                        count = sampleWaitingCount + samplingCount;
                        break;
                    }
                case HoleState.Photo:
                    {
                        int photoWaitingCount = serviceDevice.Items64.Where(o => o.State == HoleState.WaitingForPhotograph).Count();
                        int photoCount = serviceDevice.Items64.Where(o => o.State == HoleState.Photograph).Count();
                        count = photoWaitingCount + photoCount;
                        break;
                    }
            }

            if (count == StateInfos[index].StateCount)
                return;
            StateInfos[index].StateCount = count;
        }

        /// <summary>
        /// 当机器在工作时，不可转动培育仓
        /// </summary>
        private void AvoidTurned()
        {
            if(DeviceStatus==DeviceState.运行||DeviceStatus==DeviceState.即将暂停)
            {
                
                IsTurnEnabled = false;
                return;
            }
            if (RoomState == "开门")
                IsTurnEnabled = true;
            else
                IsTurnEnabled = false;
        }

        private void UpdateSampleState()
        {
            if (_leftCurrentSamples != null && _leftCurrentSamples.Count() != 0 && !LeftIsEnabled)
            {
                foreach (var sample in _leftCurrentSamples)
                {
                    var leftSample = serviceDevice.Items64.Where(o => o.Shelf == sample.Shelf && o.Index == sample.Index).First();
                    UpdateLeftSampleState(leftSample);
                }

            }

            if (_rightCurrentSamples != null && _rightCurrentSamples.Count() != 0 && !RightIsEnabled)
            {
                foreach (var sample in _rightCurrentSamples)
                {
                    var rightSample = serviceDevice.Items64.Where(o => o.Shelf == sample.Shelf && o.Index == sample.Index).First();
                    UpdateRightSampleState(rightSample);
                }
            }

        }

        private void UpdateLeftSampleState(Table_MonitorMes leftSample)
        {
            if (leftSample.State != HoleState.SAMPLING && leftSample.State != HoleState.WaitingForSample)
            {
                _leftCurrentSamples.TryDequeue(out leftSample);
                CleanLeftPlate();
            }
            else
            {
                LeftSampleId = leftSample.SampleID;
                LeftState = leftSample.State;
            }
        }

        private void UpdateRightSampleState(Table_MonitorMes rightSample)
        {
            if (RightIsEnabled)
                return;

            if (rightSample.State != HoleState.SAMPLING && rightSample.State != HoleState.WaitingForSample)
            {
                _rightCurrentSamples.TryDequeue(out rightSample);
                CleanRightPlate();
            }
            else
            {
                RightSampleId = rightSample.SampleID;
                RightState = rightSample.State;
            }
        }
        #endregion

        private void addSample()
        {
            App.Current.Dispatcher.Invoke((Action)(() =>
            {
                var expirationTimeView = new AddSample();
                DialogHost.Show(expirationTimeView, "Main");
            }));
        }

    }
}
